﻿using System;
using System.Linq;
using SellAndBuy.Application.Resources;
using SellAndBuy.Domain.Entities;
using SellAndBuy.Application.Query.DTOs;
using SellAndBuy.Application.Query.Finders;

namespace SellAndBuy.Application.Services
{
    /// <summary>
    /// Ad Query Service
    /// </summary>
    public class AdQueryService : IAdQueryService
    {
        private readonly IAdFinder _adFinder;
        private readonly IItemFinder _itemFinder;
        private readonly ICategoryFinder _categoryFinder;

        /// <summary>
        /// Constructor setting Ad repository
        /// </summary>
        /// <param name="adFinder"></param>
        /// <param name="itemFinder"></param>
        /// <param name="categoryFinder"></param>
        /// <exception cref="ArgumentNullException"><paramref name="adFinder" /> is <c>null</c>.</exception>
        public AdQueryService(IAdFinder adFinder, IItemFinder itemFinder, ICategoryFinder categoryFinder)
        {
            if (adFinder == null)
                throw new ArgumentNullException("adFinder");

            if (itemFinder == null)
                throw new ArgumentNullException("itemFinder");

            if (categoryFinder == null)
                throw new ArgumentNullException("categoryFinder");

            _adFinder = adFinder;
            _itemFinder = itemFinder;
            _categoryFinder = categoryFinder;
        }

        /// <summary>
        /// Find all Ads
        /// </summary>
        /// <returns></returns>
        public IQueryable<AdDTO> FindAds()
        {
            return _adFinder.FindAll();
        }

        /// <summary>
        /// Find all items
        /// </summary>
        /// <returns>list of items</returns>
        //public IQueryable<Item> FindItems()
        //{
        //    return _itemFinder.FindAll();
        //}

        /// <summary>
        /// Find all categories
        /// </summary>
        /// <returns>list of categories</returns>
        //public IQueryable<ItemCategory> FindCategories()
        //{
        //    return _categoryFinder.FindAll();
        //}

        /// <summary>
        /// Find all Ads by category
        /// </summary>
        /// <returns>list of Ads</returns>
        //public IQueryable<AdDTO> FindAds(ItemCategory category)
        //{
        //    if (category == null)
        //        throw new ArgumentNullException("category");

        //    return _adFinder.FindByCategory(category);
        //}

        /// <summary>
        /// Find all items by category
        /// </summary>
        /// <returns>list of items</returns>
        //public IQueryable<Item> FindItems(ItemCategory category)
        //{
        //    if (category == null)
        //        throw new ArgumentNullException("category");

        //    return _itemFinder.FindByCategory(category);
        //}

        /// <summary>
        /// Find all Ads by category
        /// </summary>
        /// <param name="category">Category</param>
        /// <param name="pageIndex">Page Index</param>
        /// <param name="pageCount">Page Count</param>
        /// <returns>list of Ads</returns>
        //public IQueryable<Ad> FindAds(ItemCategory category, int pageIndex, int pageCount)
        //{
        //    if (category == null)
        //        throw new ArgumentNullException("category");

        //    if (pageIndex < 0)
        //        throw new ArgumentException(Messages.exception_InvalidPageIndex, "pageIndex");

        //    if (pageCount <= 0)
        //        throw new ArgumentException(Messages.exception_InvalidPageCount, "pageCount");

        //    return _adFinder.FindByCategory(category, pageIndex, pageCount);
        //}

        /// <summary>
        /// Find all items by category
        /// </summary>
        /// <param name="category">Category</param>
        /// <param name="pageIndex">Page Index</param>
        /// <param name="pageCount">Page Count</param>
        /// <returns>list of items</returns>
        //public IQueryable<Item> FindItems(ItemCategory category, int pageIndex, int pageCount)
        //{
        //    if (category == null)
        //        throw new ArgumentNullException("category");

        //    if (pageIndex < 0)
        //        throw new ArgumentException(Messages.exception_InvalidPageIndex, "pageIndex");

        //    if (pageCount <= 0)
        //        throw new ArgumentException(Messages.exception_InvalidPageCount, "pageCount");

        //    return _itemFinder.FindByCategory(category, pageIndex, pageCount);
        //}

        /// <summary>
        /// Find all Ads (Paged)
        /// </summary>
        /// <param name="pageIndex">Page Index</param>
        /// <param name="pageCount">Page Count</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">pageIndex</exception>
        public IQueryable<AdDTO> FindAds(int pageIndex, int pageCount)
        {
            if (pageIndex < 0)
                throw new ArgumentException(Messages.exception_InvalidPageIndex, "pageIndex");

            if (pageCount <= 0)
                throw new ArgumentException(Messages.exception_InvalidPageCount, "pageCount");

            return _adFinder.FindAll(pageIndex, pageCount);
        }

        /// <summary>
        /// Find all items (Paged)
        /// </summary>
        /// <param name="pageIndex">Page Index</param>
        /// <param name="pageCount">Page Count</param>
        /// <returns>list of items (Paged)</returns>
        //public IQueryable<Item> FindItems(int pageIndex, int pageCount)
        //{
        //    if (pageIndex < 0)
        //        throw new ArgumentException(Messages.exception_InvalidPageIndex, "pageIndex");

        //    if (pageCount <= 0)
        //        throw new ArgumentException(Messages.exception_InvalidPageCount, "pageCount");

        //    return _itemFinder.FindAll(pageIndex, pageCount);
        //}

        /// <summary>
        /// Find Ad by id
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>Ad</returns>
        public AdDTO FindAdByID(int id)
        {
            return _adFinder.FindBy(ad => ad.ID == id).FirstOrDefault();
        }

        /// <summary>
        /// Find item by id
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>item</returns>
        //public Item FindItemByID(int id)
        //{
        //    return _itemFinder.FindBy(ad => ad.ID == id).FirstOrDefault();
        //}

        /// <summary>
        /// Find single Ad by query (Expression)
        /// </summary>
        /// <param name="query">Query</param>
        /// <returns>returned item</returns>
        //public Ad FindAdBy(Expression<Func<Ad, bool>> query)
        //{
        //    return _adFinder.FindBy(query).FirstOrDefault();
        //}

        /// <summary>
        /// Find single item by query (Expression)
        /// </summary>
        /// <param name="query">Query</param>
        /// <returns>returned item</returns>
        //public Item FindItemBy(Expression<Func<Item, bool>> query)
        //{
        //    return _itemFinder.FindBy(query).FirstOrDefault();
        //}

    }
}